package restaurante.util.persistencia;

import java.sql.SQLException;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;

public abstract class DAOJPA<T extends ObjetoPersistente> implements DAOGenerico<T> {

    //Obtém o factory a partir da unidade de persistência.
//    @PersistenceContext(type= PersistenceContextType.EXTENDED)
//    protected static EntityManager entityManager;
    protected static EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("JPA");
    protected static EntityManager entityManager = entityManagerFactory.createEntityManager();

    @Override
    public T salvar(T obj) throws Exception {
        try {
            // Inicia uma transação com o banco de dados.
            entityManager.getTransaction().begin();
            // Verifica se o objeto ainda não está salvo no banco de dados.
            if (obj.getId() == null) {
                //Salva os dados do objeto.
                entityManager.persist(obj);
                System.out.println(obj.getClass().getSimpleName()+"DAOJPA - incluir()");
            }
            else {
                //Atualiza os dados do objeto.
                obj = entityManager.merge(obj);
                System.out.println(obj.getClass().getSimpleName()+"DAOJPA - alterar()");
            }
            // Finaliza a transação.
            entityManager.getTransaction().commit();
        }
        catch (Exception e) {
            obj = null;
            throw new Exception("Erro ao obter " + e);
        }
        return obj;
    }

    @Override
    public void excluir(T obj) throws Exception {
        try {
            // Inicia uma transação com o banco de dados.
            entityManager.getTransaction().begin();
            // Remove o objeto da base de dados.
            entityManager.remove(obj);
            // Finaliza a transação.
            entityManager.getTransaction().commit();
            System.out.println(obj.getClass().getSimpleName()+"DAOJPA - excluir()");
        }
        catch (Exception e) {
            throw new Exception("Erro ao excluir " + e);
        }
    }

    @Override
    public List<T> obter(Class<T> classe) throws Exception {
        List<T> lista = null;
        try {
            Query query = entityManager.createQuery("SELECT t FROM " + classe.getSimpleName() + " t");
            lista = query.getResultList();
            System.out.println(classe.getSimpleName()+"DAOJPA - obter()");
        }
        catch (Exception e) {
            throw new Exception("Erro ao obter " + e);
        }
        return lista;
    }
    
    @Override
    public T obter(Class<T> classe, Long id) throws Exception {
        T obj = null;
        try {
            Query query = entityManager.createQuery("SELECT t FROM " + classe.getSimpleName() + " t where id = " + id);
            obj = (T)query.getSingleResult();
            System.out.println(classe.getSimpleName()+"DAOJPA - obter(Passando ID)");
        }
        catch (Exception e) {
            throw new Exception("Erro ao obter " + e);
        }
        return obj;
    }
}
